#!/usr/sbin/rsct/perl5/bin/perl 
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# "@(#)57   1.21   src/rsct/registry/cli/bin/chsrfld.perl, srcli, rsct_rpyxh, rpyxht1f3 2/22/01 16:25:40"
######################################################################
#                                                                    #
# Module: chsrfld                                                    #
#                                                                    #
# Purpose:                                                           #
#   chsrfld - Change data field values in a System Registry table.   #
#                                                                    #
# Syntax:                                                            #
#  To change field data using command line data:                     #
#   chsrfld [-h][-TV] Table Key_column==Key_value Column=Value ... ^^#
#                           Key_column==Key_value Column=Value ... ^^#
#                           ...                                      #
#                                                                    #
#  To change field data using input file data:                       #
#   chsrfld [-h][-TV] -f System_Registry_Input_File Table            #
#                                                                    #
# Flags:                                                             #
#   -h  Help. Writes this command's usage statement to stdout.       #
#   -f System_Registry_Input_File                                    #
#       File input. Instead of command line data, use an input file  #
#       containing names of tables to be altered including           #
#       descriptions of columns to be added to the new table. Format #
#       is listed under Description.                                 #
#   -T  Trace. Writes this command's trace messages to stderr.       #
#   -V  Verbose. Writes this command's verbose messages to stderr.   #
#                                                                    #
# Operands:                                                          #
#   Table   Name of the table whose data fields you wish to change.  #
#           The Table operand can contain a relative or absolute     #
#           table path.                                              #
#   Key_column Name of the primary key column for the table listed.  #
#   Key_value Key value for the row to be accessed in the table      #
#           listed.                                                  #
#   Column  Name of the column the field is in that you wish to      #
#           change.                                                  #
#   Value   New value to be placed in the field. Value will be       #
#           treated to be of the same data type as the default value #
#           for the column.                                          #
#                                                                    #
#           Multiple Column=Value pairs can be specified.            #
#                                                                    #
# Description:                                                       #
#   The chsrfld allows one or more data fields in given rows in a    #
#   System Registry table to be changed. The primary key column and  #
#   row change counter can not be changed.                           #
#                                                                    #
#   For a row identified by Key_column==Key_value, the new data      #
#   fields are specified using Column=Value pairs. For a listing of  #
#   the current column definitions, use the lssrtbldef command.      #
#                                                                    #
#   An attempt is made to process all data given.                    #
#                                                                    #
#   Data formats:                                                    #
#                                                                    #
#   Resource handles are entered as hexadecimal, using the format    #
#       (including quotes):                                          #
#       "0x######## 0x######## 0x######## 0x######## 0x########"     #
#   where '########' is a hexadecimal number. If more than 5         #
#   numbers are given, only the first 5 will be used. If less than   #
#   5 are given, 0x00000000 will be placed in the missing places.    #
#                                                                    #
#   Binary data is entered as hexadecimal, using the format          #
#       (including quotes):                                          #
#       "0x######## 0x######## 0x######## ...."                      #
#       -OR- "0x#################..."                                #
#   where '########' is a hexadecimal number. The length of the      #
#   hexadecimal string is not significant (each number could be      #
#   more or less than 8 digits). Values are stored as                #
#   given in the System Registry (the leading 0x is stripped off     #
#   for storage.)                                                    #
#                                                                    #
#   Long and unsigned long (64 bit) are expected in decimal format.  #
#   Data for individual fields within a row to be made will be       #
#   treated as the data type stored in the metadata for that column. #
#                                                                    #
#   Strings with spaces need to be enclosed in quotes.               #
#                                                                    #
#   For more information on valid data formats, please refer to the  #
#   srcli man page.                                                  #
#                                                                    #
#   Input file format:                                               #
#                                                                    #
#   Column definition data (metadata) for a new table goes in a flat #
#   text file in a stanza headed by the keyword 'DataChanges::' :    #
#   For more information on the format of the System_Registry_Input_ #
#   File, see the related man page.                                  #
#       DataChanges::                                                #
#       key 0:                                                       #
#           column_name = value                                      #
#       row 0:                                                       #
#           column_name = value                                      #
#           column_name = value                                      #
#           column_name = value                                      #
#       ...                                                          #
#                                                                    #
#   The tab at the beginning of each line is provided here for       #
#   readability but is not necessary in the input file. If more than #
#   one DataChanges stanza exists in the input file, only the first  #
#   will be read in.                                                 #
#                                                                    #
#   TODO: In future, this command will probably handle changes to    #
#   multiple rows with one call.                                     #
#                                                                    #
# Exit Values:                                                       #
#   0  SR_CLI_SUCCESS        Command completed successfully.         #
#   1  SR_CLI_REGISTRY_ERROR Command terminated due to an underlying #
#                            System Registry error.                  #
#   2  SR_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  SR_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  SR_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   5  SR_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            directory to be listed.                 #
#                                                                    #
# Examples:                                                          #
#   To change the name of column Name in  /samples/table1            #
#   chsrfld /samples/table1 Name==Daisy PetalCount=100000            #
#                                                                    #
#   To change data values in a row in /samples/People:               #
#   chsrfld /samples/People ID==10 LastName=Smith City=WA            #
#                                                                    #
#   To change a data value in a row in /samples/People where the     #
#   data field contains spaces:                                      #
#   chsrfld /samples/People ID==20 State="North Dakota"              #
#                                                                    #
#   To change a data value in a row in /samples/table1 where the     #
#   data uses resource handles:                                      #
#   chsrfld /samples/table1 Name=Mum PetalID="0x12345678 0xabcdefab  #
#      0x00000000 0x00000000 0x00000000"                             #
#                                                                    #
#   To change a data value in a row in /samples/table1 where the     #
#   data is in an input file table.definition:                       #
#   chsrfld -f table.definition /samples/table1                      #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#                                                                    #
# Outputs:                                                           #
#   stdout - help/usage statement                                    #
#   stderr - trace, verbose and error messages                       #
#                                                                    #
# External Ref:                                                      #
#   Commands: $LSMSG                                                 #
#   Extensions:  CT::SR.pm CT::CT.pm CT::SRrc.pm                     #
#   Perl library routines: Getopts::Std                              #
#   SR cli modules: SR_cli_utils.pm - init_session, isRelative       #
#      $DEFAULT_GLOBAL_MOUNT_POINT,  term_session, printCEMsg        #
#      set_session_variables, clean_session                          #
#                   SR_cli_rc.pm - CLI return codes                  #
#   CT cli modules: CT_cli_input_utils - convert_input_value         #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000929 HGJ 38317: Initial delivery.                              #
#                                                                    #
######################################################################

#--------------------------------------------------------------------#
#                                                                    #
# General Program Flow/Logic:                                        #
#                                                                    #
# A: Parse command line - get table name and other flags, operands   #
# B: Initialise session with registry, including changing the        #
#    current directory if a relative path name is given (use value   #
#    given in CT_SR_HOME)                                            #
# C: Open file to be edited - exit if it won't open                  #
# D: Process the input data, creating either field_t and             #
#    ct_char_ptr_t                                                   #
#    or field_array_t and string_array_t for single or multiple      #
#    changes                                                         #
# E: Call CT::SR::set_field_by_key or SR::fields_by_key depending on #
#    number of input pairs on the command line                       #
# F: Close session table and tree                                    #
#                                                                    #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included libraries and extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std;

use CT::CT qw(:ct_data_type_t);
use CT_cli_utils qw(printIMsg
                    printEMsg
);
use CT_cli_input_utils qw(convert_input_value 
                          process_input_file
                          process_cmdline_input
);

use CT::SR;
use CT::SRrc;
use CT::SR qw(:sr_qualifier_t);
use SR_cli_utils qw(init_session 
                    isRelative 
                    term_session 
                    printCEMsg 
                    printCIMsg  
                    $DEFAULT_GLOBAL_MOUNT_POINT
                    open_table  
                    make_value_struct_t
                    get_table_metadata
                    free_table_metadata
                    clean_session
                    set_session_variables
                    error_exit
); 
use SR_cli_rc qw(:return_codes);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
# Global constant values 
$TRUE           = 1;
$FALSE          = 0;

# Other variables
$Verbose        = $FALSE;
$Trace          = $FALSE;

$Opt_File_Input = $FALSE;               # default - see -f file input

# Messaging variables
$PROGNAME       = "chsrfld";
$MSGCAT         = "srcli.cat";
$CTDIR          = "/usr/sbin/rsct";     # Cluster directory path    
$CTBINDIR       = "$CTDIR/bin";         # Cluster Bin directory path
$LSMSG          = "$CTBINDIR/ctdspmsg"; # Display message routine
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # Msg maps used by $LSMSG  

%Cleanup = ();                          # Hash of items to cleanup
                                        # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
# Variables for use with extensions
my $Table_handle   = CT::SR::table_handle_t->new;
my $Tree_handle    = "";                # initialised in init_session

# Other variables
my $Table_name     = "";
my $Table          = "";
my @Columns        = ();
my $Column_list    = "";
my $Count          = 0;
my $Set_work_dir   = $FALSE;
my $rc             = 0;                 # assume good return code
my $Mount_point    = $DEFAULT_GLOBAL_MOUNT_POINT;


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
# TODO: Many verbose statements in this code will eventually by
# Trace statements when the facility is available as a Perl CLI
# (feature 48401)
# TODO: security on access to the table can not be further defined
# until after a security design has been implemented for the SR.
# ( feature 48402 ) Until then, the table is opened with the
# minimum security necessary to complete the command.
# TODO: FFDC handling will be implemented in Feature 48397.


# Parse the command line, exit if there are errors
($rc, $Table_name, $filename, @Columns ) = parse_cmd_line();  

# Error messages handled in parse_cmd_line
($rc == 0) || error_exit($rc);  

if ($Verbose) {
    foreach (@Columns) {
        $Column_list .= "  ".$_."\n";
    }
    $Command_line_input = "\"\n  $Table_name\n$Column_list\"";
    printIMsg("IMsgchsrfldCommandLineInput", $Command_line_input);
}


# Grab data from input file or command line.
if ($Opt_File_Input) {
    ($rc, $Column_data) = 
        process_input_file($filename, "DataChanges");

    ($rc, $Keys, $Input_data) = 
        grab_key_from_file_input($Column_data);
}
else {
    ($rc, $Column_data) = process_cmdline_input(\@ARGV);

    ($rc, $Keys, $Input_data) = 
        grab_key_from_cmdline_input($Column_data);
}
($rc == 0) || error_exit($rc); 


# Initialize Registry Library Connection
($Set_work_dir, $Table) = set_session_variables($Table_name);
($rc, $Tree_handle) = init_session($Set_work_dir);
($rc == 0) || error_exit($rc);  
$Cleanup{Session} = $Tree_handle;


$Verbose && printIMsg("IMsgchsrfldTableName", $Table_name, $Table);


# Call CT::SR::open_table to open table to be edited 
($rc, $Table_handle) = open_table($Tree_handle, $Table,
                        $Table_name, SR_WRITE);

($rc == 0) || error_exit($rc);  
push @{$Cleanup{Tables}}, $Table_handle;

# Grab table metadata here, just in case there have to be
# multiple calls to set_field or set_fields
($rc, $Metadata) = get_table_metadata($Table_handle);
($rc == 0) || error_exit($rc);  

# Get the column metadata in a Perl structure so is more
# easily manipulated
$Column_defs = $Metadata->getColumnDefs();

# Free the metadata
$rc = free_table_metadata($Metadata);
($rc == 0) || error_exit($rc);  

# Check to see how many entries per each row to be edited.
# If only one field needs to be changed, call change_single_field,
# which uses CT::SR::set_field_by_key.
# Otherwise, call change_multiple fields, which uses
# CT::SR::set_fields_by_key.

$Key_index = 0;
foreach $Entry (@$Input_data) {
    $Entry_count = scalar(@{$Entry->[1]});
    if ($Entry_count == 1) { 
        $rc = change_single_field($Table_handle, $Table_name, 
                    $Column_defs, $Keys->[$Key_index++], $Entry);
    }
    else {
        $rc = change_multiple_fields($Table_handle, $Table_name, 
                    $Column_defs, $Keys->[$Key_index++], $Entry );
    }

    # Check the return code from the previous subroutine
    ($rc == 0) || error_exit($rc);  
}


# Clean session before quitting - Exit with least non-zero error code
$rc = clean_session($Tree_handle, $Mount_point, $Table_handle);

# Clear the cleanup hash
%Cleanup = ();
($rc == 0) || error_exit($rc);  

# Return the highest error code
exit $rc;

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# grab_key_from_cmdline_input:                                       #
#  Grab all key entries from the input data, convert them to data_   #
#  element_t hash, remove the keys from the input data. Create two   #
#  arrays - one that holds the key values, one that holds the row    #
#  data, and return these.                                           #
#                                                                    #
# Parameters:                                                        #
#   $input_data - data to be scanned for key value                   #
#                                                                    #
# Return values:                                                     #
#   $local_rc     - local return code                                #
#   \@row_keys    - keys to be used to access rows                   #
#   \@output_data - data to be used to change fields in a given row  #
#                                                                    #
# Global variables modified:                                         #
#   None                                                             #
#--------------------------------------------------------------------#
sub grab_key_from_cmdline_input
{
my $input_data = shift;

my $local_rc = 0;
my @row_keys = ();
my @output_data = ();
my $temp= $input_data->[0];
my ($entry, $row);
my $index = 0;

foreach $entry (@$input_data) {
    if ($entry->[1][0][1] =~ /^=/) {
        my $row_key;
        # This should be the format of the line,
        $row_key->{name} = $entry->[1][0][0];
        $row_key->{value} = $entry->[1][0][1];
        $row_key->{value} =~ s/^=\s*//;
        push @row_keys, $row_key;
        $temp_array = $entry->[1];
        shift @$temp_array;
        push @output_data, $entry; 
    }
    else {
        my $row_key = $entry->[1][0][0]."=".$entry->[1][0][1];
        printEMsg("EMsgchsrfldIncorrectKeyDefn", $row_key);
        return(SR_CLI_USER_ERROR);
    }
}

return ($local_rc, \@row_keys, \@output_data);
}   # end grab_key_from_cmdline_input


#--------------------------------------------------------------------#
# grab_key_from_file_input:                                          #
#   Grab all key entries from the input data, convert them to data_  #
#   element_t hash, remove the keys from the input data. Create two  #
#   arrays - one that holds the key values, one that holds the row   #
#   data to be changed.  Siple checking done here to make sure that  #
#   the input file format was as expected.                           #
#                                                                    #
# Parameters:                                                        #
#   $input_data - data to be scanned for key value                   #
#                                                                    #
# Return values:                                                     #
#   $local_rc     - local return code                                #
#   \@row_keys    - keys to be used to access rows                   #
#   \@output_data - data to be used to change fields in a given row  #
#                                                                    #
# Global variables modified:                                         #
#   None                                                             #
#--------------------------------------------------------------------#
sub grab_key_from_file_input
{
my ($input_data) = @_;

my $local_rc = 0;
my @output_data = ();
my @row_keys = ();
my $row_next = 0;

foreach $entry (@$input_data) {
    if (($entry->[0] =~ /^key \d+/) && ($row_next == 0)) {
        # set up the hash, skip to next value
        my $row_key;
        $row_key->{name} = $entry->[1][0][0];
        $row_key->{value} = $entry->[1][0][1];
        push @row_keys, $row_key;
        $row_next = 1;
    }
    elsif (($entry->[0] =~ /^row \d+/) && ($row_next == 1)) {
        # set up the hash, skip to next value
        $row_next = 0;
        push @output_data, $entry;
        next;
    }
    else {
        printEMsg("EMsgchsrfldIncorrectKeyDefn", "DataChanges::");
        return(SR_CLI_USER_ERROR);
    }
}

return ($local_rc, \@row_keys, \@output_data); 
}   # end grab_key_from_file_input


#--------------------------------------------------------------------#
# change_single_field:                                               #
#   Use CT::SR::set_field_by_key to change a single column name.     #
#   Calls get_column_types and set_field_value to set up data for    #
#   the extension call.                                              #
#                                                                    #
# Parameters:                                                        #
#   $table_handle - handle to table to get type information on       #
#   $table_name   - name of the table being used                     #
#   $col_defs     - column metadata                                  #
#   $row_key      - key for the row to be changed                    #
#   $input_data   - data to be used to change the field              #
#                                                                    #
# Return values:                                                     #
#   $local_rc     - local return code                                #
#                                                                    #
# Global variables modified:                                         #
#   None                                                             #
#--------------------------------------------------------------------#
sub change_single_field
{
# Gather input parameters
my ($table_handle, $table_name, $col_defs, $row_key_holder, 
                        $input_data) = @_;

# Initialise local variables
my $local_rc  = 0;
my $found = 0;
my ($entry, $new_field, $column_name, $column_value);
my $row_key = {};

# make the value struct t here, then scan the column defs
# and convert the row key value over correctly. Need the
# data type from the column defs.

foreach $entry (@$col_defs) {
    if ($row_key_holder->{name} eq $entry->{name}) {
        ($local_rc, $row_key->{value}) = 
                convert_input_value($entry->{type}, 
                        $row_key_holder->{value}, 
                        $entry->{sd_defn}->[1]);
        $row_key->{type} = $entry->{type};
        last;
    }
}   

$column_name = $input_data->[1][0][0];
$column_value = $input_data->[1][0][1];

foreach $entry (@$col_defs) {
    if ($entry->{name} eq $column_name) {
        ($local_rc, $new_field->{value}) = 
                convert_input_value($entry->{type}, 
                        $column_value, 
                        $entry->{sd_defn}->[1]);
        $new_field->{type} = $entry->{type};
        $new_field->{name} = $column_name;
        $found = $TRUE;
        last;
    }
}
if ($found != $TRUE) {
    printCEMsg("EMsgSRcliInvalidColumnData");
    return SR_CLI_USER_ERROR;
}

if ($local_rc != 0) { return $local_rc; }


# Call extension to change/set the field values
$Trace && print STDERR "Calling CT::SR::set_field_by_key\n";

$local_rc = CT::SR::set_field_by_key($table_handle, $row_key, 
                        $new_field->{name}, $new_field );
$Trace && 
    print STDERR "CT::SR::set_field_by_key return code: $local_rc\n";

$local_rc = error_check("sr_set_field_by_key", $local_rc, $table_name);

return($local_rc);
}   # end change_single_field


#--------------------------------------------------------------------#
# change_multiple_fields:                                            #
#   Use CT::SR::set_fields_by_key to change multiple column names.   #
#   Calls get_column_types and set_field_value to set up data for    #
#   the extension call.                                              #
#                                                                    #
# Parameters:                                                        #
#   $table_handle - handle to table to get type information on       #
#   $table_name   - name of the table being used                     #
#   $col_defs     - column metadata                                  #
#   $row_key      - key for row to be edited                         #
#   $input_data   - data to be used to change fields in the row      #
#                                                                    #
# Return values:                                                     #
#   $local_rc     - local return code                                #
#                                                                    #
# Global variables modified:                                         #
#   None                                                             #
#--------------------------------------------------------------------#
sub change_multiple_fields
{
my ($table_handle, $table_name, $col_defs, $row_key, 
                $input_data) = @_;

# Set up local variables
my $local_rc = 0;
my ($entry, $count, $columns_set, $value_struct_t);

# Make the value struct t here, then scan the column defs
# and convert the row key value over correctly. Need the
# data type from the column defs.

foreach $entry (@$col_defs) {
    if ($row_key->{name} eq $entry->{name}) {
        ($local_rc, $row_key->{value}) = 
                convert_input_value($entry->{type}, 
                    $row_key->{value}, 
                    $entry->{sd_defn}->[1]);
        $row_key->{type} = $entry->{type};
        last;
    }
}   

($local_rc, $value_struct_t, $columns_used) = 
    make_value_struct_t($col_defs, "", 0, $input_data->[1]);

# Call extension to change/set the field values
$Trace && print STDERR "Calling CT::SR::set_fields_by_key\n";

$local_rc = CT::SR::set_fields_by_key($table_handle, 
                        $row_key, $columns_used, $value_struct_t);
$Trace && 
    print STDERR "CT::SR::set_fields_by_key return code: $local_rc\n";

$local_rc = error_check("sr_set_fields_by_key", $local_rc, $table_name);
return($local_rc);
}   # end change_multiple_fields


#--------------------------------------------------------------------#
# error_check:                                                       #
#   Checks the return code from the SR function.  If an error is     #
#   detected appropriate error messages will be displayed and        #
#   SR CLI return code set.                                          #
#                                                                    #
# Parameters:                                                        #
#   $sr_function  - Name of the SR function that was called and      #
#                   whose error code we are checking.                #
#   $sr_rc        - SR function return code.                         #
#   $table_name   - Name of the table trying to create.              #
#                                                                    #
# Return values:                                                     #
#   None.                                                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($sr_function, $sr_rc, $table_name) = @_;
my $rc = 0;

# Check the result of CT::SR::set_fields_by_key
if ($sr_rc != 0){
    if ($sr_rc == SR_NO_PERMISSION) {
        printEMsg("EMsgchsrfldNoPermission", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_TABLE) {
        printEMsg("EMsgchsrfldNoTable", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_KEY_NOT_FOUND) {
        printEMsg("EMsgchsrfldKeyNotFound");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_COLUMN) {
        printEMsg("EMsgchsrfldNoColumn");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NULL_POINTER) {
        printEMsg("EMsgchsrfldNullPointer");
        $rc = SR_CLI_USER_ERROR;
    }
    else {
        printEMsg("EMsgchsrfldErrorChangingField", $table_name);
        printCEMsg("EMsgSRcliSRCommandFailure", $sr_function, $sr_rc);
        $rc = SR_CLI_REGISTY_ERROR;
    }
}

return ($rc);
}   # end error_check


#--------------------------------------------------------------------#
# parse_cmd_line:                                                    #
#   Uses getopts() to grab flags on the command line. parses the     #
#   command data, (checks the syntax of the key_column value and     #
#   otherwise makes sure there is data to be changed) then returns   #
#   the table to be modified, the count of changes to be made and    #
#   the columns to be changed.                                       #
#                                                                    #
# Return values:                                                     #
#   $local_rc - local return code                                    #
#   $table_name - table name to be modified                          #
#   $filename - input filename when getting data from file.          #
#   @columns - array containing column=value pairs, with the first   #
#              entry being the key_column==value necessary for       #
#              matching the row to be edited                         #
#                                                                    #
# Global variables modified:                                         #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Opt_File_Input    output   True (-f) file input (-f <filename>) #
#--------------------------------------------------------------------#
sub parse_cmd_line
{
# Set up local variables
my $local_rc = 0;
my @columns = ();
my $table_name = "";
my $filename = "";
my %opts = ();

if (getopts('hf:TV', \%opts) == 0) {     # Parse input flags
    printCEMsg("EMsgSRcliInvalidFlag");
    print_usage();
    return SR_CLI_BAD_FLAG;
}                  

# Print usage and exit if -h used
if (defined $opts{h}) {   
    print_usage();
    exit(0);    
}

# Get table name from input.
$table_name = shift @ARGV;
if ((!$table_name ) || ($table_name =~ /=/)) {
    printCEMsg("EMsgSRcliNoTableName");
    print_usage();
    return SR_CLI_BAD_OPERAND;
}

if (defined $opts{f}) {
    $Opt_File_Input = $TRUE;
    $filename = $opts{f};
    if ($#ARGV >= 0) {
        printCEMsg("EMsgSRcliTooManyOperands");
        print_usage();
        return SR_CLI_BAD_OPERAND;
    }
}

# Make sure if no -f flag that we have at least the
# key==value and Column=Value (at least 2 operands)
if (!defined $opts{f} && $#ARGV < 1) {
    printCEMsg("EMsgSRcliNoColumnData");
    print_usage();
    return SR_CLI_BAD_OPERAND;
}

# Set Trace flag if requested
if (defined $opts{T}) {
    $Trace = $TRUE;
}

# Set Verbose flag if requested
if (defined $opts{V}) {
    $Verbose = $TRUE;
}

return ($local_rc, $table_name, $filename, @columns);
}   # end parseCmdLine

#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsgchsrfldUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
